package com.wt.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wt.admin.entity.LoginAccount;
import com.wt.admin.entity.Register;
import com.wt.admin.entity.SmsCode;
import com.wt.admin.entity.WqunAccount;
import com.wt.admin.mapper.WqunAdminMapper;
import com.wt.admin.service.SmsCodeService;
import com.wt.admin.service.WqunAdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wt.commonutils.JwtUtils;
import com.wt.commonutils.R;
import com.wt.commonutils.ResultMess;
import com.wt.encryptionPass.Md5Util;
import com.wt.encryptionPass.SaltUtils;
import com.wt.servicebase.exceptionhandler.exceptionhandler.WQUNException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 账号表 服务实现类
 * </p>
 *
 * @author wt
 * @since 2023-07-31
 */
@Service
public class WqunAdminServiceImpl extends ServiceImpl<WqunAdminMapper, WqunAccount> implements WqunAdminService {
    @Autowired
    private SmsCodeService smsCodeService;

    @Autowired
    RedisTemplate redisTemplate;

    private final ResultMess resultMess = new ResultMess();

    //账号注册
    @Override
    @Transactional
    public boolean registerAccount(Register register) {
        //判断电话号是否符合规格
        legalPhone(register.getAccountPhone());

        //判断用户ID,电话号码是否存在
        if (phoneYetRegister(register.getAccountPhone())){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_IS_EXIST);
        }

        //转换实体类，对账号验证码进行验证
        SmsCode smsCode = new SmsCode();
        smsCode.setPhone(register.getAccountPhone());
        smsCode.setSms(register.getSms());
        if (!smsCodeService.checkSms(smsCode)){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_CODE_ALIKE);
        }

        //判断两次密码是否一致
        if(!register.getAccountPass().equals(register.getSecondPass())){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_PASS_NOT_ALIKE);
        }

        //密码准确性验证
        legalPass(register.getAccountPass());

        //将账号密码赋值给Account类，进行账号登记
        WqunAccount wqunAccount = new WqunAccount();
        wqunAccount.setPhone(register.getAccountPhone());
        wqunAccount.setPass(register.getAccountPass());


        // 对密码加密MD5+盐
        // 生成盐
        String salt = SaltUtils.getSalt(4);
        wqunAccount.setSalt(salt);
        // 进行加密
        String passWord = Md5Util.MD5Lower(wqunAccount.getPass(), salt);
        wqunAccount.setPass(passWord);

        //验证全部通过，进行用户注册
        int insert = baseMapper.insert(wqunAccount);

        if (insert != 1){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_INTERNET);
        }
        //获取该用户自动自动生成的ip,进行创建人以及修改人的初始化
        QueryWrapper<WqunAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",wqunAccount.getPhone());
        wqunAccount = baseMapper.selectOne(wrapper) ;
        if(wqunAccount == null){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_INTERNET);
        }
        wqunAccount.setCreateBy(wqunAccount.getId());
        wqunAccount.setUpdateBy(wqunAccount.getId());
        insert = baseMapper.updateById(wqunAccount);
        if (insert != 1){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_INTERNET);
        }
        return true;
    }

    //验证码登录
    @Override
    public String loginCode(SmsCode smsCode) {
        //判断账号是否符合规格
        legalPhone(smsCode.getPhone());

        //判断是否存在此账号
        if(!phoneYetRegister(smsCode.getPhone())){
            throw new WQUNException(20003,resultMess.LOGIN_INFO_PHONE_IS_NOT_EXIST);
        }

        //是否存在此验证码
        String sms = (String) redisTemplate.opsForValue().get(smsCode.getPhone());
        if(sms == null){
            throw new WQUNException(20003,resultMess.LOGIN_INFO_PHONE_CODE_IS_NULL);

        }

        //判断手机号和验证码是否一致
        if(!sms.equals(smsCode.getSms())){
            throw new WQUNException(20003,resultMess.LOGIN_INFO_PHONE_CODE_NOT_ALIKE);
        }

        //验证通过，生成token字符串，使用jwt工具类，传递给前端作为登录凭证
        return JwtUtils.getJwtToken(smsCode.getPhone());
    }

    //账号密码登录
    @Override
    public String loginAccount(LoginAccount loginAccount) {
        //判断账号是否符合规格
        legalPhone(loginAccount.getAccountPhone());

        //判断是否存在此账号
        if(!phoneYetRegister(loginAccount.getAccountPhone())){
            throw new WQUNException(20003,resultMess.LOGIN_INFO_PHONE_IS_NOT_EXIST);
        }

        //获取该账号信息
        QueryWrapper<WqunAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", loginAccount.getAccountPhone());
        WqunAccount loginAccountByPhone = baseMapper.selectOne(wrapper);


        //密码加密
        String pass = Md5Util.MD5Lower(loginAccount.getAccountPass(), loginAccountByPhone.getSalt());
        //加密后比对
        if(!loginAccountByPhone.getPass().equals(pass)){
            throw new WQUNException(20003,resultMess.LOGIN_INFO_PHONE_PASS);
        }

        //验证通过，生成token字符串，使用jwt工具类，传递给前端作为登录凭证
        return JwtUtils.getJwtToken(loginAccount.getAccountPhone());
    }

    @Override
    public R findAccountPage(int pageSize,int currentPage,String selectFind,String selectFindValue) {
        IPage<WqunAccount> resultPage = new Page<>(currentPage,pageSize);
        QueryWrapper<WqunAccount> queryWrapper = new QueryWrapper<>();
        if(!Objects.equals(selectFind, "NULL") && !Objects.equals(selectFindValue, "NULL")){
            queryWrapper.like(true,selectFind,selectFindValue);
        }
        queryWrapper.orderByDesc("id");
        if(!Objects.equals(selectFind, "is_delete")){
            queryWrapper.eq("is_delete","0");
        }
        IPage<WqunAccount> iPage = baseMapper.selectPage(resultPage, queryWrapper);
        List<WqunAccount> findAccountPage = iPage.getRecords();
        long total = iPage.getTotal();

        return R.ok().data("findAccountPage",findAccountPage).data("total",baseMapper.selectPage(resultPage, queryWrapper).getTotal());

    }


    //判断用户电话号码是否存在
    @Override
    public boolean phoneYetRegister(String phone) {
        //判断用户电话号码是否存在
        QueryWrapper<WqunAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",phone);

        return  baseMapper.selectCount(wrapper) > 0;

    }


    //密码准确性验证
    @Override
    public void legalPass(String pass) {
        //密码准确性验证
        //长度检查
        if(pass == null || pass.length()<6){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_PASS_MIN_6);
        }
        if(pass.length()>20){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_PASS_MAX_20);
        }

        //准确性检查,判断是否全是英文或数字
        if(!pass.matches("^[0-9a-zA-Z]+$")){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_PASS_NOT_NUMBER_AND_ENGLISH);
        }
    }

    //判断用户ID，电话号码，密码等重要字段是否为空（待定）
    @Override
    public void legalPhone(String phone) {
        //判断用户ID，电话号码，密码等重要字段是否为空（待定）
        if (phone == null ||phone.length() != 11)
        {
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_LEN_MIN_11);
        }

        //判断电话号码是否为纯数字
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        boolean isNumber =  pattern.matcher(phone).matches();
        if(!isNumber){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_NOT_IS_NUMBER);
        }

        String regex = "^[1][3,4,5,7,8,9][0-9]{9}$";
        Pattern p = Pattern.compile(regex);
        Matcher match = p.matcher(phone);


        if(!match.matches()){
            throw new WQUNException(20003,resultMess.REGISTER_INFO_PHONE_FORMAT);
        }

    }
}
